<template>
  <el-form
    class="message-form"
    :model="form"
    ref="formRef"
    :rules="rules"
    label-width="auto"
  >
    <el-form-item label="作业科目" required prop="subject" v-if="isHomeworkMsg">
      <el-radio-group v-model="form.subject">
        <el-radio
          v-for="subject in subjectOptions"
          :key="subject.subject_num"
          :value="subject.subject_num"
          >{{ subjectMap[subject.subject_num] }}</el-radio
        >
      </el-radio-group>
    </el-form-item>
    <el-form-item label="通知标题" required prop="title">
      <el-input
        v-model="form.title"
        :maxlength="TITLE_LIMIT.MAX"
        :minlength="TITLE_LIMIT.MIN"
      />
    </el-form-item>
    <div class="flex-between">
      <el-form-item
        label="通知时间"
        prop="publishTime"
        class="message-form-item"
      >
        <el-date-picker
          :disabled-date="commonDateDisable"
          v-model="form.publishTime"
          type="datetime"
          format="YYYY-MM-DD HH:mm"
          placeholder="立即发布"
          popper-class="my-date-picker"
        />
      </el-form-item>
    </div>
    <el-form-item label="通知内容" prop="description" class="textarea">
      <el-input
        type="textarea"
        :rows="15"
        v-model="form.description"
        placeholder="请输入通知内容"
        :maxlength="CONTENT_LIMIT"
      />
      <div class="count">{{ form.description.length }}/2000</div>
    </el-form-item>
    <el-form-item label="通知附件">
      <el-upload
        style="width: 100%"
        :auto-upload="false"
        :on-change="customUpload"
        :on-exceed="onFileUploadExceed"
        :limit="FILE_LIMIT"
        :show-file-list="false"
        :accept="acceptFileType.join(',')"
      >
        <el-button style="margin-top: 0.04rem" link type="primary">
          点击上传附件
        </el-button>
      </el-upload>
      <div class="flex file-box">
        <div class="file-item" v-for="(file, index) in form.file" :key="index">
          <img
            src="@/assets/images/assignment/delete.png"
            @click="onDeleteFile(index)"
            class="hover close-img"
            alt=""
          />
          <img class="file-img" :src="getFileImg(file.name)" />
          <div class="file-name">{{ file.name }}</div>
        </div>
      </div>
    </el-form-item>
  </el-form>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useAuthStore } from '@/stores'
import { storeToRefs } from 'pinia'
import dayjs from 'dayjs'
import _ from 'lodash'
import { uploadFile, getFileImg, beforeUpload } from '@/utils/upload'
import { ElMessage, ElLoading } from 'element-plus'
import { commonDateDisable } from '@/views/assignment/util'
import { subjectMap } from '@/constants'
import { MsgStatusEnum, MsgTypeEnum } from '../constant'

const props = defineProps({
  // 通知类型
  msgType: { type: Number, required: true }
})

// 当前通知类型是否为作业通知
const isHomeworkMsg = computed(() => {
  return props.msgType === MsgTypeEnum.HOMEWORK
})

const authStore = useAuthStore()
const { userInfo, globalSubjectList } = storeToRefs(authStore)
const formRef = ref()

const subjectOptions = computed(() =>
  _.uniqBy(globalSubjectList.value, 'subject_num').sort(
    (a, b) => a.subject_num - b.subject_num
  )
)

const form = ref({
  subject: subjectOptions.value[0].subject_num,
  title: `${dayjs().format('YYYY-MM-DD')}${isHomeworkMsg.value ? '作业' : '班级'}通知`,
  publishTime: null,
  description: '',
  file: []
})

const TITLE_LIMIT = {
  MIN: 1,
  MAX: 50
}
const CONTENT_LIMIT = 2000

const rules = {
  publishTime: [
    {
      validator: (_, value, callback) => {
        if (dayjs(value).unix() <= dayjs().unix()) {
          callback(new Error('发布时间应大于当前时间'))
        }
        callback()
      },
      trigger: 'change'
    }
  ],
  title: [
    {
      required: true,
      validator: (_, value, callback) => {
        if (value.length < TITLE_LIMIT.MIN || value.length > TITLE_LIMIT.MAX) {
          callback(
            new Error(
              `请输入${TITLE_LIMIT.MIN}-${TITLE_LIMIT.MAX}个中、英文字符或数字`
            )
          )
        }
        callback()
      },
      trigger: 'change'
    }
  ],
  description: [
    {
      validator: (_, value, callback) => {
        if (!value.trim().length && !form.value.file.length) {
          callback(new Error(`请输入通知内容`))
        }
        callback()
      },
      trigger: 'change'
    }
  ]
}

const FILE_LIMIT = 5
const acceptFileType = [
  '.mp3',
  '.wav',
  '.ogg',
  '.wma',
  '.mp4',
  '.avi',
  '.mov',
  '.wmv',
  '.flvmkv',
  '.jpg',
  '.jpeg',
  '.png',
  '.gif',
  '.doc',
  '.docx',
  '.ppt',
  '.pptx',
  '.xls',
  '.xlsx',
  '.pdf',
  '.txt'
]
const onFileUploadExceed = () => {
  ElMessage.info('已达到上传上限')
}
// 上传文件
const customUpload = async file => {
  let isContinue = beforeUpload(file)
  if (!isContinue) {
    return
  }
  let name = file.name
  name = name.slice(0, name.lastIndexOf('.'))
  const ext = `.${file.name.split('.').pop()}`
  if (!acceptFileType.includes(ext)) {
    ElMessage.error('不支持的文件格式')
    return
  }
  let reg =
    /[`~!@#$%^&*()+=<>?:"{}|,.\\/;'\\[\]·！#￥（——）：；“”‘、，|。？、[\]]/im
  if (reg.test(name)) {
    ElMessage.error(`文件名不能包含+ ?><\\/*|": 等特殊字符，请修改后重新上传`)
    return
  }
  const loading = ElLoading.service({
    lock: true,
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.3)'
  })
  const res = await uploadFile(file)
  loading.close()
  form.value.file.push(res)
}

const onDeleteFile = index => {
  form.value.file.splice(index, 1)
}

// 检查表单数据
const validateForm = async ruleForm => {
  return await ruleForm.validate(() => {})
}

// 提交表单
const getForm = async () => {
  if (!(await validateForm(formRef.value))) return null

  const param = {
    title: form.value.title,
    content: form.value.description,
    type: props.msgType,
    user_id: userInfo.value.userId,
    user_name: userInfo.value.userName,
    user_type: 1,
    school_id: userInfo.value.school_id,
    notify_time: form.value.publishTime
      ? dayjs(form.value.publishTime).unix()
      : dayjs().unix(),
    subject: form.value.subject,
    attachment_url: form.value.file.map(item => ({
      url: item.url,
      name: item.name
    })),
    // 没有发布时间即为立即发布
    release: form.value.publishTime
      ? MsgStatusEnum.UNPUBLISHED
      : MsgStatusEnum.PUBLISHED
  }
  return param
}

// 编辑消息初始化表单
const initForm = msgInfo => {
  const time =
    typeof msgInfo.notify_time === 'number' &&
    String(msgInfo.notify_time).length === 10
      ? msgInfo.notify_time * 1000
      : new Date(msgInfo.notify_time).getTime()
  form.value = {
    subject: msgInfo.subject,
    title: msgInfo.title,
    // 若发布时间小于当前时间，设定为立即发布
    publishTime: time < Date.now() ? null : time,
    description: msgInfo.content,
    file: msgInfo.attachment_url
  }
  console.log('initForm =>', form.value)
}

defineExpose({
  getForm,
  initForm
})
</script>

<style lang="less" scoped>
.message-form {
  max-width: 100%;

  /* stylelint-disable ebag/selector-class-pattern */
  :deep(.el-form-item__label, .el-checkbox) {
    height: 40px;
    line-height: 40px;
  }
  .message-form-item {
    width: 48% !important;
  }
  .message-small-item {
    width: 30% !important;
  }
  .file-box {
    flex-wrap: wrap;
    gap: 20px;

    .file-item {
      position: relative;
      width: 44px;
      height: 44px;
      margin-top: 10px;

      .close-img {
        position: absolute;
        right: 0;
        top: 0;
        width: 14px;
        height: 14px;
        transform: translate(50%, -50%);
        display: none;
      }

      &:hover {
        .close-img {
          display: block;
        }
      }

      .file-img {
        width: 44px;
        height: 44px;
      }

      .file-name {
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        text-align: center;
        color: rgba(4, 11, 26, 0.5);
        font-size: 14px;
        line-height: 1;
      }
    }
  }

  .textarea {
    position: relative;
    margin-bottom: 25px;
    .count {
      position: absolute;
      right: 10px;
      bottom: -35px;
      color: #cdced1;
    }
  }

  .return-box {
    gap: 20px;
    margin-bottom: 10px;
  }

  /* stylelint-disable ebag/selector-class-pattern */
  :deep(.el-form-item) {
    font-size: @size-big !important;
    .el-form-item__label {
      padding-right: 40px;
      font-size: @size-big !important;
      color: #181818;
      &::before {
        display: none;
      }
    }
    .el-input__wrapper {
      box-sizing: border-box;
      height: 39px;
    }
    .el-input__inner {
      font-size: @size-big !important;
    }
    .el-button {
      font-size: @size-big !important;
      margin-bottom: 10px;
    }
    .el-textarea__inner {
      font-size: @size-big !important;
    }
    .el-form-item__label,
    .el-checkbox {
      height: 40px;
      line-height: 40px;
    }
    .el-radio__label {
      font-size: @size-big;
    }
    .el-date-editor--datetime {
      .el-input__wrapper {
        width: 200px;
      }
    }
  }

  .setting-icon {
    margin-left: 20px;
    font-size: 20px;
  }
  .wrong-return {
    :deep(.el-form-item__content) {
      flex: unset;
    }
  }
}
</style>

<!-- eslint-disable -->
<style lang="less">
.my-date-picker {
  .el-date-table {
    font-size: @base-size;
  }
  .el-input--small {
    height: 30px;
    font-size: @base-size;
  }
  .is-text {
    display: none;
  }
}
</style>
